/*
 * @(#)Handler.java    �汾�� 2010-10-30
 * 
 * Version information
 * 
 * Copyright notice
 */

package cn.edu.nju.software.localserver;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;

import cn.edu.nju.software.XML.XMLParser;
import cn.edu.nju.software.XML.XMLProducer;
import cn.edu.nju.software.XML.XMLValidator;
import cn.edu.nju.software.beans.AccountBean;
import cn.edu.nju.software.beans.CidSidBean;
import cn.edu.nju.software.beans.CourseBean;
import cn.edu.nju.software.beans.StudentBean;
import cn.edu.nju.software.managers.AccountTManage;
import cn.edu.nju.software.managers.CourseTManage;
import cn.edu.nju.software.managers.CourseStudentTManage;
import cn.edu.nju.software.managers.StudentTManage;

/**
 * Class description goes here.
 * 
 * @version �汾�� 2010-10-30
 * @author lijinsheng
 */
public class Handler {
	/* A class implementation comment can go here. */
	private Handler() {
	}

	// handle the log of the user
	public static LogType handleLog(DataInputStream inputStream) {
		String userName = "";
		String password = "";
		try {
			userName = inputStream.readUTF();
			password = inputStream.readUTF();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		LogType logType = LogType.LogFail;

		// do with database;
		try {
			if (AccountTManage.checkLogin(userName, password)) {
				if (AccountTManage.getSId(userName).equals("-1")) {
					logType = LogType.Administrator;
				} else {
					logType = LogType.Student;
				}
			}
		} catch (SQLException e) {

			e.printStackTrace();
		}

		return logType;
	}

	// handle the changePassword of the user
	public static boolean handleChangePassword(DataInputStream inputStream) {
		String userName = "";
		String originalPassword = "";
		String newPassword = "";

		try {
			userName = inputStream.readUTF();
			originalPassword = inputStream.readUTF();
			newPassword = inputStream.readUTF();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// do with database;
		boolean changeSuccessful = false;
		try {
			changeSuccessful = AccountTManage.changePassword(userName,
					originalPassword, newPassword);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return changeSuccessful;
	}

	// handle the personal information
	public static ArrayList<String> handlePerInformationView(
			DataInputStream inputStream) {
		String userName = "";
		try {
			userName = inputStream.readUTF();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// do with database
		ArrayList<String> personalInformation = new ArrayList<String>();
		ArrayList<String> sids = new ArrayList<String>();
		StudentBean student = new StudentBean();

		try {
			sids.add(AccountTManage.getSId(userName));
			student = StudentTManage.getStudents(sids).get(0);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		personalInformation.add(student.getId());
		personalInformation.add(student.getName());
		personalInformation.add(student.getGender());
		personalInformation.add(student.getInstitute());

		return personalInformation;
	}

	// handle course view of the student
	public static ArrayList<ArrayList<CourseBean>> handleCourseView(
			DataInputStream inputStream) {
		String userName = "";
		try {
			userName = inputStream.readUTF();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// do with database;
		ArrayList<ArrayList<CourseBean>> allCourses = new ArrayList<ArrayList<CourseBean>>();
		ArrayList<CourseBean> chosenCourses = new ArrayList<CourseBean>();
		ArrayList<CourseBean> unChosenCourses = new ArrayList<CourseBean>();

		try {
			chosenCourses
					.addAll(CourseTManage
							.getChoosedCourses(CourseStudentTManage
									.getChosenCourses(AccountTManage
											.getSId(userName))));
			unChosenCourses
					.addAll(CourseTManage
							.getChoosableCourses(CourseStudentTManage
									.getChosenCourses(AccountTManage
											.getSId(userName))));
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		allCourses.add(unChosenCourses);
		allCourses.add(chosenCourses);
		return allCourses;
	}

	// handle the choose course of the student
	// handle the uncibe course of the student
	public static boolean handleChooseCourse(DataInputStream inputStream) {
		String userName = "";
		String sid = "";
		String cid = "";
		String courseDepartment = "";

		ArrayList<StudentCourseBean> currentChosenStudentCourseBeans = new ArrayList<StudentCourseBean>();
		try {
			userName = inputStream.readUTF();

			try {
				sid = AccountTManage.getSId(userName);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			while (!(cid = inputStream.readUTF()).equals("course_end")) {
				courseDepartment = inputStream.readUTF();
				currentChosenStudentCourseBeans.add(new StudentCourseBean(sid,
						cid, courseDepartment));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		ArrayList<StudentCourseBean> previousChosenStudentCourseBeans = new ArrayList<StudentCourseBean>();
		try {
			for (CourseBean course : CourseTManage
					.getChoosedCourses(CourseStudentTManage
							.getChosenCourses(sid))) {
				previousChosenStudentCourseBeans.add(new StudentCourseBean(sid,
						course.getId(), course.getInstitute()));
			}
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		ArrayList<StudentCourseBean> newRemoveStudentCourseBean = new ArrayList<StudentCourseBean>();
		ArrayList<StudentCourseBean> giveupRemoveStudentCourseBean = new ArrayList<StudentCourseBean>();
		for (StudentCourseBean newStudentCourseBean : currentChosenStudentCourseBeans) {
			for (StudentCourseBean giveupStudentCourseBean : previousChosenStudentCourseBeans) {
				if (newStudentCourseBean.getCid().equals(
						giveupStudentCourseBean.getCid())) {
					newRemoveStudentCourseBean.add(newStudentCourseBean);
					giveupRemoveStudentCourseBean.add(giveupStudentCourseBean);
				}
			}
		}
		currentChosenStudentCourseBeans.removeAll(newRemoveStudentCourseBean);
		previousChosenStudentCourseBeans
				.removeAll(giveupRemoveStudentCourseBean);

		ArrayList<StudentCourseBean> outerNew = new ArrayList<StudentCourseBean>();
		for (StudentCourseBean studentCourseBean : currentChosenStudentCourseBeans) {
			if (!studentCourseBean.getCourseDepartment().equals("A")) {
				outerNew.add(studentCourseBean);
			}
		}

		ArrayList<StudentCourseBean> outerGiveup = new ArrayList<StudentCourseBean>();
		for (StudentCourseBean studentCourseBean : previousChosenStudentCourseBeans) {
			if (!studentCourseBean.getCourseDepartment().equals("A")) {
				outerGiveup.add(studentCourseBean);
			}
		}

		ArrayList<CidSidBean> choose = new ArrayList<CidSidBean>();
		ArrayList<CidSidBean> giveUp = new ArrayList<CidSidBean>();

		for (StudentCourseBean studentCourseBean : currentChosenStudentCourseBeans) {
			choose.add(new CidSidBean(studentCourseBean.getCid(),
					studentCourseBean.getSid()));
		}

		for (StudentCourseBean studentCourseBean : previousChosenStudentCourseBeans) {
			giveUp.add(new CidSidBean(studentCourseBean.getCid(),
					studentCourseBean.getSid()));
		}

		boolean result = false;

		result = new SendToIntegrateServer()
				.toIntegrateSelectCourseInformation(outerNew);
		result = result
				&& new SendToIntegrateServer()
						.toIntegrateUnSelectCourseInformation(outerGiveup);
		try {
			result = result && CourseStudentTManage.chooseCourse(choose);
			result = result && CourseStudentTManage.giveUpCourse(giveUp);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	// handle the administrator course view
	public static ArrayList<CourseBean> handleAdministratorCourseView() {
		ArrayList<CourseBean> allCourses = new ArrayList<CourseBean>();

		try {
			allCourses.addAll(CourseTManage.getAllCourses());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return allCourses;
	}

	// handle administrator add course
	public static boolean handleAddCourse(DataInputStream inputStream) {

		String courseId = "";
		String courseName = "";
		String courseTeacher = "";
		int courseGrade = 0;
		int courseTime = 0;
		String coursePlace = "";
		String courseInstitute = "A";
		boolean isSharable = false;
		ArrayList<CourseBean> courses = new ArrayList<CourseBean>();

		try {
			while (!(courseId = inputStream.readUTF()).equals("course_end")) {
				courseName = inputStream.readUTF();
				courseTeacher = inputStream.readUTF();
				courseGrade = inputStream.readInt();
				courseTime = inputStream.readInt();
				coursePlace = inputStream.readUTF();
				isSharable = inputStream.readBoolean();
				courses.add(new CourseBean(courseId, courseName,
						courseInstitute, courseTeacher, courseGrade,
						courseTime, coursePlace, isSharable));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		boolean result = false;

		try {
			result = CourseTManage.addCourses(courses);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;
	}

	// handle administrator delete course
	public static boolean handleDeleteCourse(DataInputStream inputStream) {
		ArrayList<String> courseIds = new ArrayList<String>();
		String courseId = "";
		try {
			while (!(courseId = inputStream.readUTF()).equals("course_end")) {
				courseIds.add(courseId);
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		boolean result = true;

		// send the delete course information to the integrateServer
		result = new SendToIntegrateServer()
				.toIntegrateDeleteCourseInformation(courseIds);
		try {
			result = result && CourseTManage.deleteCourse(courseIds);
			result = result && CourseStudentTManage.deleteCourse(courseIds);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	// handle administrator view the student
	public static ArrayList<StudentBean> handleAdministratorStudentView() {
		ArrayList<StudentBean> students = new ArrayList<StudentBean>();
		try {
			students.addAll(StudentTManage.getAllStudents());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return students;
	}

	// handle administrator add student
	public static boolean handleAddStudent(DataInputStream inputStream) {

		String userName = "";
		String password = "";
		String number = "";
		String name = "";
		String sex = "";
		String department = "A";
		ArrayList<AccountBean> accounts = new ArrayList<AccountBean>();
		ArrayList<StudentBean> students = new ArrayList<StudentBean>();

		try {
			while (!(userName = inputStream.readUTF()).equals("student_end")) {
				password = inputStream.readUTF();
				number = inputStream.readUTF();
				name = inputStream.readUTF();
				sex = inputStream.readUTF();
				accounts.add(new AccountBean(userName, password, number));
				students.add(new StudentBean(number, name, sex, department));
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		boolean result = false;

		try {
			result = AccountTManage.addAccount(accounts);
			result = result && StudentTManage.addStudents(students);
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return result;
	}

	// handle administrator delete Student
	public static boolean handleDeleteStudent(DataInputStream inputStream) {

		System.out.println("enter delete");
		ArrayList<String> studentIds = new ArrayList<String>();
		String studentId = "";
		try {
			while (!(studentId = inputStream.readUTF()).equals("student_end")) {
				studentIds.add(studentId);
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		boolean result = true;

		// send delete student information to the integrateserver

		 result = new SendToIntegrateServer()
		 .toIntegrateDeleteStudentInformation(studentIds);

		try {
			result = result && AccountTManage.deleteAccount(studentIds);
			result = result && StudentTManage.deleteStudent(studentIds);
			result = result && CourseStudentTManage.deleteStudent(studentIds);
		} catch (SQLException e) { // TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;
	}

	// handle administrator share course
	public static boolean handleShareCourse() {

		try {
			CourseTManage.addCourses(new SendToIntegrateServer()
					.sendShareCourseInformation());
			return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	// get the course from the database and store in a file
	public static File handleFromIntegrationCourseShare() {
		File xmlFile = null;
		try {
			xmlFile = XMLProducer.produceCourseFile(CourseTManage
					.getSharedCourses());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return xmlFile;
	}

	// add the course select to the database
	public static boolean handleFromIntegrationCourseSelect(
			DataInputStream inputStream) {
		File xmlFile = new File("E:\\CourseSelectFromIntegrate" + Server.number
				+ ".xml");
		FileHandler.readFile(xmlFile, inputStream);
		if (XMLValidator.validate(xmlFile, new File(
				"xmlFiles/BStudentCourseSchema.xsd"))) {
			try {
				return CourseStudentTManage.chooseCourse(XMLParser
						.parseStudentCourse(xmlFile));
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return true;
		} else {
			return false;
		}
	}

	// delete the course chosen relation from the database
	public static boolean handleFromIntegrationCourseUnScibe(
			DataInputStream inputStream) {
		File xmlFile = new File("E:\\CourseUnselectFromIntegrate"
				+ Server.number + ".xml");
		FileHandler.readFile(xmlFile, inputStream);
		if (XMLValidator.validate(xmlFile, new File(
				"xmlFiles/BStudentCourseSchema.xsd"))) {
			try {
				return CourseStudentTManage.giveUpCourse(XMLParser
						.parseStudentCourse(xmlFile));
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return true;
		} else {
			return false;
		}
	}

	// delete the chosen relation about the course
	public static boolean handleFromIntegrationDeleteCourse(
			DataInputStream inputStream) {
		File xmlFile = new File("E:\\DeleteCourse" + Server.number + ".xml");
		FileHandler.readFile(xmlFile, inputStream);
		if (XMLValidator.validate(xmlFile, new File("xmlFiles/ACIDSchema.xsd"))) {
			ArrayList<CidSidBean> delete = new ArrayList<CidSidBean>();

			for (String cid : XMLParser.parseCourseID(xmlFile)) {
				try {
					for (String sid : CourseStudentTManage.getDeleteCoReSt(cid)) {
						delete.add(new CidSidBean(cid, sid));
					}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			try {
				CourseStudentTManage.giveUpCourse(delete);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return true;
		} else {
			return false;
		}
	}

	// delete the chosen relation about the student
	public static boolean handleFromIntegrationDeleteStudent(
			DataInputStream inputStream) {

		File xmlFile = new File("E:\\DeleteStudent" + Server.number + ".xml");
		FileHandler.readFile(xmlFile, inputStream);
		if (XMLValidator.validate(xmlFile, new File("xmlFiles/ASIDSchema.xsd"))) {
			ArrayList<CidSidBean> delete = new ArrayList<CidSidBean>();

			for (String sid : XMLParser.parseStudentID(xmlFile)) {
				try {
					for (String cid : CourseStudentTManage.getDeleteStReCo(sid)) {
						delete.add(new CidSidBean(cid, sid));
					}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			try {
				CourseStudentTManage.giveUpCourse(delete);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return true;
		} else {
			return false;
		}
	}
}
